package com.sychip.fhc.app.data.repo.impl


import com.fhc.base.ymdHMS
import com.sychip.fhc.app.data.repo.WsnDeviceRssiRepo
import com.sychip.fhc.app.data.repo.WsnTestRecordRepo
import com.sychip.fhc.app.data.source.convert.toDto
import com.sychip.fhc.app.data.source.convert.toEntity
import com.sychip.fhc.app.data.source.dao.WsnDeviceRssiDao
import com.sychip.fhc.app.data.source.dao.WsnTestRecordDao
import com.sychip.fhc.app.data.source.dto.WsnDeviceDto
import com.sychip.fhc.app.data.source.dto.WsnDeviceRssiDto
import com.sychip.fhc.app.data.source.dto.WsnTestRecordDto
import com.sychip.fhc.di.IoDispatcher
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton


@Singleton
class WsnTestRecordRepoImpl @Inject constructor(
    private val wsnTestRecordDao: WsnTestRecordDao,
    @IoDispatcher private val dispatcher: CoroutineDispatcher
) : WsnTestRecordRepo {
    override fun observeAll(usbId: String): Flow<List<WsnTestRecordDto>> {
        return wsnTestRecordDao.observeAll(usbId).map { it.toDto() }
    }
    override suspend fun getAll(usbId: String): List<WsnTestRecordDto> {
        return withContext(dispatcher) {
            wsnTestRecordDao.getAll(usbId).toDto()
        }
    }

    override suspend fun add(usbId: String, fromTime: Long, routeName: String): Flow<WsnTestRecordDto> = flow {
        val task = WsnTestRecordDto(
            usbId = usbId,
            fromTime = fromTime,
            routeName = routeName,
        )
        wsnTestRecordDao.upsert(task.toEntity())
        emit(task)
    }


    override suspend fun add(usbId: String, fromTime: Long, toTime: Long, projectName: String, routeName: String): Flow<WsnTestRecordDto> = flow {
        val task = WsnTestRecordDto(
            usbId = usbId,
            fromTime = fromTime,
            toTime = toTime,
            projectName = projectName,
            routeName = routeName
        )
        wsnTestRecordDao.upsert(task.toEntity())
        emit(task)
    }

    override suspend fun getByFromTime(fromTime: Long): WsnTestRecordDto {
        return withContext(dispatcher) {
            wsnTestRecordDao.getByFromTime(fromTime).toDto()
        }
    }

    override suspend fun updateByFromTime(
        fromTime: Long, toTime: Long, projectName: String
    ): WsnTestRecordDto {
        val task = getByFromTime(fromTime).copy(
            toTime = toTime,
            projectName = projectName,
        )
        wsnTestRecordDao.upsert(task.toEntity())
        return task
    }

    override suspend fun deleteByFromTime(fromTime: Long): Int {
        return wsnTestRecordDao.deleteByFromTime(fromTime)
    }

    override suspend fun deleteAll(usbId: String): Int {
        return wsnTestRecordDao.deleteAll(usbId)
    }


}
